package com.mazaiting.manager.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mazaiting.common.core.domain.result.Option;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.BaseException;
import com.mazaiting.common.core.ex.exceptions.BusinessException;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import com.mazaiting.manager.convert.IDictItemConverter;
import com.mazaiting.manager.domain.entity.SysDictItem;
import com.mazaiting.manager.domain.form.DictItemForm;
import com.mazaiting.manager.domain.query.DictItemPageQuery;
import com.mazaiting.manager.domain.vo.dict.DictItemPageVO;
import com.mazaiting.manager.mapper.ISysDictItemMapper;
import com.mazaiting.manager.service.ISysDictItemService;
import com.mazaiting.mybatisplus.domain.vo.BasePageVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 字典数据表 服务实现类
 * </p>
 *
 * @author mazaiting
 * @since 2022-10-16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysDictItemServiceImpl extends ServiceImpl<ISysDictItemMapper, SysDictItem> implements ISysDictItemService {

    private final IDictItemConverter dictItemConverter;

    @Override
    public BasePageVO<DictItemPageVO> listDictItemPages(DictItemPageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        // 关键字
        String name = queryParams.getName();
        // 类型码值
        String typeCode = queryParams.getTypeCode();

        // 查询数据
        Page<SysDictItem> dictItemPage = lambdaQuery()
                .like(StringUtils.hasLength(name), SysDictItem::getName, name)
                .eq(StringUtils.hasLength(typeCode), SysDictItem::getTypeCode, typeCode)
                .select(SysDictItem::getId, SysDictItem::getName, SysDictItem::getValue, SysDictItem::getStatus)
                .page(new Page<>(pageNum, pageSize));

        // 实体转换
        Page<DictItemPageVO> pageResult = dictItemConverter.entity2Page(dictItemPage);
        return BasePageVO.success(pageResult);
    }

    @Override
    public DictItemForm getDictItemFormData(Long id) throws EmptyObjectException {
        // 获取entity
        Optional<SysDictItem> sysDictItemOpt = lambdaQuery().eq(SysDictItem::getId, id)
                .select(
                        SysDictItem::getId,
                        SysDictItem::getTypeCode,
                        SysDictItem::getName,
                        SysDictItem::getValue,
                        SysDictItem::getStatus,
                        SysDictItem::getSort,
                        SysDictItem::getRemark
                ).oneOpt();
        if (sysDictItemOpt.isEmpty()) {
            throw new EmptyObjectException(ResultCode.DICT_ITEM_EMPTY);
        }

        // 实体转换
        return dictItemConverter.entity2Form(sysDictItemOpt.get());
    }

    @Override
    public boolean save(DictItemForm dictItemForm) throws BusinessException {
        Optional<SysDictItem> sysDictItemOpt = lambdaQuery().eq(SysDictItem::getTypeCode, dictItemForm.getTypeCode())
                .eq(SysDictItem::getValue, dictItemForm.getValue())
                .oneOpt();

        if (sysDictItemOpt.isPresent()) {
            throw new BusinessException(ResultCode.DICT_ITEM_EXIST);
        }

        // 实体对象转换 form->entity
        SysDictItem entity = dictItemConverter.form2Entity(dictItemForm);
        // 持久化
        return this.save(entity);
    }

    @Override
    public boolean update(DictItemForm dictItemForm) throws BaseException {
        // 根据 ID 查询
        SysDictItem sysDictItem = getById(dictItemForm.getId());
        if (Objects.isNull(sysDictItem)) {
            throw new EmptyObjectException(ResultCode.DICT_ITEM_EMPTY);
        }
        // 查询类型码值+码值, 并且ID不等于当前值的数据
        Optional<SysDictItem> sysDictItemOpt = lambdaQuery().eq(SysDictItem::getTypeCode, dictItemForm.getTypeCode())
                .eq(SysDictItem::getValue, dictItemForm.getValue())
                .ne(SysDictItem::getId, dictItemForm.getId()).oneOpt();
        if (sysDictItemOpt.isPresent()) {
            throw new BusinessException(ResultCode.DICT_ITEM_EXIST);
        }
        // form -> entity
        SysDictItem entity = dictItemConverter.form2Entity(dictItemForm);
        // 更新
        return updateById(entity);
    }

    @Override
    public boolean deleteByIds(String idsStr) {
        // 获取 ID 列表
        List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).toList();
        // 删除字典数据项
        return this.removeByIds(ids);
    }

    @Override
    public List<Option<String>> listDictItemsByTypeCode(String typeCode) {
        // 数据字典项, 只查询可用项
        List<SysDictItem> dictItems = lambdaQuery().eq(SysDictItem::getTypeCode, typeCode)
                .select(SysDictItem::getValue, SysDictItem::getName)
                .eq(SysDictItem::getStatus, true)
                .list();

        // 转换下拉数据
        return Optional.ofNullable(dictItems).orElse(new ArrayList<>()).stream()
                .map(dictItem -> new Option<>(dictItem.getValue(), dictItem.getName()))
                .toList();
    }

}
